home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / utility / mu17_ext.zip / USERID.C < prev    next >
C/C++ Source or Header  |  1994-03-07  |  7KB  |  266 lines

  1. /******************************************************************
  2. * MultiUser - MultiUser Task/File Support System          *
  3. * --------------------------------------------------------------- *
  4. * Get User ID data - AmigaShell script support utility          *
  5. *-----------------------------------------------------------------*
  6. *                                  *
  7. * ⌐ 1993 Fabian Nu±ez  -  contact me at: fnunez@cs.uct.ac.za      *
  8. *                                  *
  9. ******************************************************************/
  10.  
  11. #include <proto/exec.h>
  12. #include <proto/dos.h>
  13. #include <dos/dos.h>
  14. #include <exec/memory.h>
  15. #include <libraries/multiuser.h>
  16. #include <proto/multiuser.h>
  17.  
  18. #define ARG_USERID    0
  19. #define ARG_GROUPID    1
  20. #define ARG_NAME    2
  21. #define ARG_GROUPNAME    3
  22. #define ARG_UID     4
  23. #define ARG_GID     5
  24. #define ARG_HOMEDIR    6
  25. #define ARG_SHELL    7
  26. #define ARG_FILE    8
  27. #define ARG_UACCESS    9
  28. #define ARG_GACCESS    10
  29. #define ARG_MANAGER    11
  30.  
  31. /* some error retcodes... */
  32.  
  33. #define FILE_NOT_FOUND (-1L)
  34. #define CANNOT_EXAMINE (-2L)
  35.  
  36. /* Other stuff */
  37.  
  38. #define BITSPERWORD (BITSPERLONG / 2)
  39.  
  40. /*
  41.    Modified V37 struct FileInfoBlock for MultiUser, for the benefit of
  42.    owners of V37 (but not V39) includes. This struct is functionally
  43.    identical to that in the V39 Includes, but the original is not mine
  44.    to give away...
  45. */
  46.  
  47. struct muFSFileInfoBlock
  48. {
  49.    LONG mufib_DiskKey;
  50.    LONG mufib_DirEntryType;
  51.    char mufib_FileName[108];
  52.    LONG mufib_Protection;
  53.    LONG mufib_EntryType;
  54.    LONG mufib_Size;
  55.    LONG mufib_NumBlocks;
  56.    struct DateStamp mufib_Date;
  57.    char mufib_Comment[80];    /* Up to here, all by Commodore-Amiga, Inc. */
  58.    UWORD mufib_OwnerUID;
  59.    UWORD mufib_OwnerGID;
  60.    char mufib_Reserved[32];    /* length is same as for standard FIB */
  61. };
  62.  
  63. /* Prototypes */
  64. void done(struct muUserInfo *,struct muGroupInfo *,LONG,LONG,STRPTR);
  65. void itoa(LONG,STRPTR);
  66. ULONG muGetFileOwner(STRPTR,ULONG *);
  67.  
  68. static char _version_[] = "\0$VER:UserID 39.14 (2.2.94)\r\n";
  69.  
  70. volatile struct muBase *muBase;
  71.  
  72. /* Don't include stdio and other useless stuff  ;) */
  73. void _main(void)
  74. {
  75.     struct muUserInfo *uinfo = NULL;
  76.     struct muGroupInfo *ginfo = NULL;
  77.     struct RDArgs *args = NULL;
  78.     ULONG user;
  79.     ULONG retcode;
  80.     UBYTE *returned = NULL;
  81.     LONG argarray[] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
  82.     UBYTE bitarray[] = {1,2,4,8,16,32,64,128};
  83.     UBYTE bits;
  84.     LONG i;
  85.  
  86.     /* Open libraries */
  87.     muBase = (struct muBase *)OpenLibrary(MULTIUSERNAME,MULTIUSERVERSION);
  88.     if (!muBase)
  89.     {
  90.     PutStr("I need multiuser.library V39");
  91.     Exit(ERROR_INVALID_RESIDENT_LIBRARY);
  92.     }
  93.  
  94.     args = ReadArgs("USERID/S,GROUPID/S,NAME=USERNAME/S,GROUPNAME/S,UID/S,GID/S," \
  95.             "HOMEDIR/S,SHELL/S,FILE/K,UACCESS/K/N,GACCESS/K/N,MANAGER/S",
  96.             argarray,NULL);
  97.  
  98.     if (!args)
  99.     {
  100.     PrintFault(IoErr(),NULL);
  101.     done(NULL,NULL,user,RETURN_ERROR,NULL);
  102.     }
  103.  
  104.     for (i=0,bits = 0;i < ARG_FILE;i++)
  105.     if (argarray[i]) bits += bitarray[i];
  106.  
  107.     /* Get muUserInfo, muGroupInfo structs */
  108.     if (!(uinfo = muAllocUserInfo()))
  109.     done(NULL,NULL,0,RETURN_FAIL,"Insufficient memory");
  110.     if (!(ginfo = muAllocUserInfo()))
  111.     done(uinfo,NULL,0,RETURN_FAIL,"Insufficient memory");
  112.  
  113.     /* store info in 'returned' */
  114.  
  115.     /* if FILE is specified, use owner of file, otherwise use this user */
  116.     if (argarray[ARG_FILE])
  117.     {
  118.     user = muGetFileOwner((STRPTR)argarray[ARG_FILE],&retcode);
  119.  
  120.     switch (retcode)
  121.     {
  122.         case FILE_NOT_FOUND:
  123.         done(uinfo,ginfo,user,RETURN_ERROR,"File not found");
  124.  
  125.         case CANNOT_EXAMINE:
  126.         done(uinfo,ginfo,user,RETURN_ERROR,"Cannot examine file");
  127.     }
  128.     }
  129.     else
  130.     user = muGetTaskOwner(NULL); /* get uid, gid of owner of this task */
  131.  
  132.     if (user)
  133.     {
  134.     uinfo->uid = (UWORD) (user >> BITSPERWORD);
  135.     ginfo->gid = (UWORD) (user & muMASK_GID);
  136.     uinfo = muGetUserInfo(uinfo,muKeyType_uid);
  137.     ginfo = muGetGroupInfo(ginfo,muKeyType_gid);
  138.  
  139.     if (argarray[ARG_MANAGER])  /* Actually want info on user's manager */
  140.     {
  141.         uinfo->uid = ginfo->MgrUid;
  142.         uinfo = muGetUserInfo(uinfo,muKeyType_uid);     /* Get info on manager */
  143.         ginfo->gid = uinfo->gid;
  144.         ginfo = muGetGroupInfo(ginfo,muKeyType_gid);    /* Get info on manager's group */
  145.     }
  146.  
  147.     if (uinfo)
  148.     {
  149.         switch(bits)
  150.         {
  151.         case   0 : /* Default case is case 1 */
  152.         case   1 : returned = uinfo->UserID;
  153.                break;
  154.         case   2 : returned = ginfo->GroupID;
  155.                break;
  156.         case   4 : returned = uinfo->UserName;
  157.                break;
  158.         case   8 : returned = ginfo->GroupName;
  159.                break;
  160.         case  16 : returned = "     ";
  161.                itoa(uinfo->uid,returned);
  162.                break;
  163.         case  32 : returned = "     ";
  164.                itoa(ginfo->gid,returned);
  165.                break;
  166.         case  64 : returned = uinfo->HomeDir;
  167.                break;
  168.         case 128 : returned = uinfo->Shell;
  169.                break;
  170.         default  : done(uinfo,ginfo,user,RETURN_ERROR,"One switch only!");
  171.         }
  172.     }
  173.     else
  174.     {
  175.         if (argarray[ARG_MANAGER])
  176.         done(uinfo,ginfo,user,RETURN_WARN,"User has no manager");
  177.         else
  178.         done(uinfo,ginfo,user,RETURN_ERROR,"Unknown user");
  179.     }
  180.     }
  181.     else done(uinfo,ginfo,user,RETURN_ERROR,"Nobody"); /* task or file owned by
  182.                                nobody */
  183.  
  184.     if (argarray[ARG_UACCESS] && argarray[ARG_GACCESS])
  185.     done(uinfo,ginfo,user,RETURN_ERROR,"One access keyword only!");
  186.     else
  187.     {
  188.     if (argarray[ARG_UACCESS])
  189.         if (((ULONG)uinfo->uid) < *(ULONG *)argarray[ARG_UACCESS])
  190.         done(uinfo,ginfo,user,RETURN_WARN,returned);
  191.         else user = 1; /* remove normal WARN if root is logged on */
  192.  
  193.     if (argarray[ARG_GACCESS])
  194.         if (((ULONG)uinfo->gid) < *(ULONG *)argarray[ARG_GACCESS])
  195.         done(uinfo,ginfo,user,RETURN_WARN,returned);
  196.         else user = 1; /* remove normal WARN as above */
  197.     }
  198.  
  199.     done(uinfo,ginfo,user,0L,returned);
  200. }
  201.  
  202. void done(struct muUserInfo *uinfo,struct muGroupInfo *ginfo,LONG user,
  203.       LONG retcode,STRPTR returned)
  204. {
  205.     if (returned)
  206.     {
  207.     PutStr(returned);
  208.     PutStr("\n");
  209.     }
  210.  
  211.     if (uinfo) muFreeUserInfo(uinfo);
  212.     if (ginfo) muFreeGroupInfo(ginfo);
  213.     CloseLibrary((struct Library *)muBase);
  214.  
  215.     if (!retcode)
  216.     {
  217.     if (user == 0)
  218.         Exit(RETURN_ERROR); /* ERROR or no-one home today */
  219.     else if ((user & muMASK_GID) == 0xFFFF)
  220.         Exit(RETURN_WARN);  /* WARN - a root is logged in or security violation */
  221.     else Exit(RETURN_OK);       /* OK - nothing to remark */
  222.     }
  223.     else Exit(retcode);
  224. }
  225.  
  226. void itoa(LONG number,STRPTR string)
  227. {
  228.     LONG i;
  229.  
  230.     for (i=4;i;i--)
  231.     {
  232.         string[i] = '0' + number % 10;
  233.         number /= 10;
  234.     }
  235.     string[i] = '0' + number % 10; /* Last digit */
  236. }
  237.  
  238. ULONG muGetFileOwner(STRPTR filename,ULONG *errorcode)
  239. {
  240.     BPTR lock;
  241.     __aligned struct muFSFileInfoBlock mufib;
  242.     ULONG user;
  243.  
  244.     if (!(lock = Lock(filename,SHARED_LOCK)))
  245.     {
  246.     *errorcode = FILE_NOT_FOUND;
  247.     return NULL;
  248.     }
  249.  
  250.     if (!Examine(lock,&mufib))
  251.     {
  252.     UnLock(lock);
  253.     *errorcode = CANNOT_EXAMINE;
  254.     return NULL;
  255.     }
  256.  
  257.     user = (ULONG)((((UWORD)mufib.mufib_OwnerUID) << BITSPERWORD) | (UWORD)mufib.mufib_OwnerGID);
  258.  
  259.     *errorcode = NULL;
  260.  
  261.     UnLock(lock);
  262.  
  263.     return user;
  264. }
  265.  
  266.